
const PENDING = 'pending'

const FULFILLED = 'fulfilled'

const REJECTED = 'rejected'

class MyPromise{
  constructor(executor){
    executor(this.resolve,this.reject)
  }
  value = undefined
  reason = undefined
  //初始化状态为等待
  status = PENDING;

  successCallback = [];
  failCallback = [];

  resolve=value=>{
    //不是pending就停止
    if(this.status!== PENDING){
      return
    }
    this.status = FULFILLED
    this.value = value

    //若果遇到异步 就先获取successCallback状态 如果有就执行 相当于在resolve完成后执行then
    // this.successCallback && this.successCallback(this.value)
    //当存在多个then的情况
    while(this.successCallback.length){
      this.successCallback.shift()(this.value)
    }
  }
  reject = reason =>{
    if(this.status!== PENDING){
      return
    }
    this.status = REJECTED
    this.reason = reason
    // this.failCallback && this.failCallback(this.reason)
    while(this.failCallback.length){
      this.failCallback.shift()(this.reason)
    }
  }
  then(successCallback,failCallback){

    let promise2 = new MyPromise((res, rej)=>{
      //resolve会把值传给下一个then
      if(this.status== FULFILLED){
        let x = successCallback(this.value)
        //判断x值是否是promise对象 不是就直接传值
        resolvePromise(x,res,rej);
      //将状态传给then回调函数
      // successCallback(this.value)
    }
  else if(this.status == REJECTED){
      failCallback(this.reason)
    }else{
      this.successCallback.push(successCallback);
      this.failCallback.push(failCallback);
    }
    });
    return promise2
  }
  static all (array){
    //结果数组
    let result = []
    //计算数组元素个数
    let index = 0;

    return new Promise((resolve,reject)=>{
      function addData(key,value){
        result[key] = value;
        index++;
        //当执行完所有数组元素后执行resolve给then传值
        if(index === array.length){
          resolve(result)
        }
      }
      //循环要素
      for (let i=0; i<array.length;i++){
        let current  = array[i]
        if(current instanceof MyPromise){
          //判断下传入的promise的状态
          current.then(value=>addData(i,value),reason=>reject(reason))
        }else{
          //普通值直接放入
          addData(i,array[i])
        }
      }
    })
  }
  finally(callback){
    //返回promise对象 用then获取前面promise状态
    console.log(this);
    return this.then(value=>{
      callback()
      return value
    },reason=>{
      callback();
      throw reason;
    })
  }
  catch(failCallback){
    //等于then里面的失败回调
    return this.then(undefined,failCallback)
  }
  static resolve(value){
    if(value instanceof MyPromise){
      return value
    }else{
      return new MyPromise(resolve=>resolve(value))
    }

  }
}

function resolvePromise(x, resolve, reject)
{
  if(x instanceof MyPromise){
    //若果是promise对象就先判断一下状态
    x.then(resolve,reject)
  }else{
    resolve(x)
  }
}

module.exports = MyPromise
